# TODO: fix the indentation, should be 4 spaces not 2

from google.appengine.ext import db

class Trip(db.Model):
  description = db.StringProperty()
  price       = db.FloatProperty()
  start_date  = db.DateProperty()
  end_date    = db.DateProperty()
  is_member_only   = db.BooleanProperty('Member only trip price?') 
  is_promo_allowed = db.BooleanProperty('Promo code allowed?')
  trip_number = db.IntegerProperty()
  ski_season  = db.StringProperty()

  def dict_update(self, data):
    for (key, value) in data.iteritems():
      if hasattr(self, key): 
        setattr(self, key, value)
 
  @staticmethod 
  def ids_exist(id_list):
      trips = Trip.get_by_id(id_list)
      if len(id_list) > len(trips):
          return False
      if None in trips:
          return False
      return True      

  # business logic for validating trip ids for signup
  # ids should exist, trips should not be in the past, two Trips may
  #    not have the same trip number and ski season combination
  # TODO: validate that the user has not selected two trip-items from the same trip number
  # TODO: validate that the user has not selected a trip in the past
  @staticmethod
  def validate_ids_for_signup(id_list):
      errors = []
      if not Trip.ids_exist(id_list):
          errors.append('One of the specified trip ids does not exist.') 
      return errors

class PromoCode(db.Model):
  promo_code = db.StringProperty()
  name       = db.StringProperty()
  discount   = db.FloatProperty()
  #status: 0 - not given out; 1 - given out not redeemed; 2 - redeemed
  status     = db.IntegerProperty(default=0)

# Represents an order for sign ups
class TripOrder(db.Model):
  billing_first_name = db.StringProperty(required=True)
  billing_last_name  = db.StringProperty(required=True)
  billing_email= db.EmailProperty(required=True)
  trips        = db.ListProperty(int)
  promo_code   = db.ReferenceProperty(PromoCode, required=False)
  total        = db.FloatProperty()
  pay_method   = db.StringProperty()
  amount_paid  = db.FloatProperty() 
  #transaction_id is the check info or the PayPal transaction id
  transaction_id = db.StringProperty(required=False)
  date_created = db.DateProperty(auto_now_add=True)

CHOICES_BEDDING = [
    'twin bed',
    'queen bed (sharing)',
]

CHOICES_PICKUP = [
    'EC - El Cerrito',
    'SJ - San Jose',
    'SAC - Sacramento',
]

CHOICES_GENDER = [
    'female',
    'male',
]

CHOICES_MEMBERSHIP = [
    'NSC Member',
    'BAC Member',
    'Guest - First Bus Trip',
    'Guest - Former NSC Member',
    'Guest',
    'Other',
]

# This is user entered data for a signup
class TripSignupInfo(db.Model):
  first_name   = db.StringProperty(required=True)
  last_name    = db.StringProperty(required=True)
  membership   = db.StringProperty('Membership Status', choices=CHOICES_MEMBERSHIP, default='Other', required=True)
  email        = db.EmailProperty(required=True)
  pickup       = db.StringProperty(choices=CHOICES_PICKUP, required=True)
  gender       = db.StringProperty(choices=CHOICES_GENDER, required=True) 
  bedding      = db.StringProperty(choices=CHOICES_BEDDING, required=True)
  roommate     = db.StringProperty()
  address      = db.StringProperty(required=True)
  city         = db.StringProperty(required=True)
  state        = db.StringProperty(required=True)
  zip          = db.StringProperty(required=True)
  phone_main = db. StringProperty('Phone number', required=True)
  phone_alt   = db. StringProperty('Alternate phone')
  emergency_contact = db.StringProperty(required=True)
  emergency_phone   = db.StringProperty(required=True)
  insurance_name    = db.StringProperty() 
  insurance_policy  = db.StringProperty()
  license_plate     = db.StringProperty()
  how_heard         = db.StringProperty('How did you hear about this trip?')
  is_senior    = db.BooleanProperty('Senior?')
  is_smoker    = db.BooleanProperty('Smoker?')
  is_lesson    = db.BooleanProperty('Need Lesson?')
  is_beginnger = db.BooleanProperty('First Time Beginner?')
  is_first_bus = db.BooleanProperty('First Bus Trip?')
  is_front_bus = db.BooleanProperty('Front of bus preferred?')
  is_snack     = db.BooleanProperty('Bring a snack to share?')
  is_vege      = db.BooleanProperty('Vegetarian?')
  date_created = db.DateProperty(auto_now_add=True)

# Represents a spot on the trip. Requires an order and signup info
class TripSpot(db.Model):
  trip_signup_info = db.ReferenceProperty(TripSignupInfo, required=True) 
  trip_order  = db.ReferenceProperty(TripOrder, required=True)
  is_waiver   = db.BooleanProperty(default=False)
  is_paid     = db.BooleanProperty(default=False) 
  room        = db.StringProperty()
  #denormalized fields for convenience
  trip_number = db.IntegerProperty()
  ski_season  = db.StringProperty()
  date_created = db.DateProperty(auto_now_add=True)
  
